/* bootpack‚ÌƒƒCƒ“ */

#include "bootpack.h"
#include <stdio.h>
#include "net.h"
#include "package.h"

#define KEYCMD_LED		0xed

void HariMain(void)
{
	struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
	struct SHTCTL *shtctl;
	char s[100];
	unsigned char  dma_str[100];
	struct FIFO32 fifo, keycmd,fifo_net;
	int fifobuf[128], keycmd_buf[32];
	int *net_buf;
	int mx, my, i, cursor_x, cursor_c;
	unsigned int memtotal;
	struct MOUSE_DEC mdec;
	struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
	unsigned char *buf_back, buf_mouse[256], *buf_win, *buf_cons;
	struct SHEET *sht_back, *sht_mouse, *sht_win, *sht_cons;
	struct TASK *task_a, *task_cons;
	struct TIMER *timer;
    
    struct mac_addr mynodeid;// save mac
    struct NetworkDriver driver;
    
    union netcard txdnet,test_pack;// package to send
    //union recvpack *rxdnet;// package save recv
    char *bytebuf;
    int  send_data_length;
    send_data_length=68;
    int back_row=8;
    
    unsigned src_ip[4]={10,211,55,3};
    unsigned dest_ip[4]={10,211,55,1};
	static char keytable0[0x80] = {
		0,   0,   '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', 0,   0,
		'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', 0,   0,   'A', 'S',
		'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0,   0,   ']', 'Z', 'X', 'C', 'V',
		'B', 'N', 'M', ',', '.', '/', 0,   '*', 0,   ' ', 0,   0,   0,   0,   0,   0,
		0,   0,   0,   0,   0,   0,   0,   '7', '8', '9', '-', '4', '5', '6', '+', '1',
		'2', '3', '0', '.', 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
		0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
		0,   0,   0,   0x5c, 0,  0,   0,   0,   0,   0,   0,   0,   0,   0x5c, 0,  0
	};
	static char keytable1[0x80] = {
		0,   0,   '!', 0x22, '#', '$', '%', '&', 0x27, '(', ')', '~', '=', '~', 0,   0,
		'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '`', '{', 0,   0,   'A', 'S',
		'D', 'F', 'G', 'H', 'J', 'K', 'L', '+', '*', 0,   0,   '}', 'Z', 'X', 'C', 'V',
		'B', 'N', 'M', '<', '>', '?', 0,   '*', 0,   ' ', 0,   0,   0,   0,   0,   0,
		0,   0,   0,   0,   0,   0,   0,   '7', '8', '9', '-', '4', '5', '6', '+', '1',
		'2', '3', '0', '.', 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
		0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
		0,   0,   0,   '_', 0,   0,   0,   0,   0,   0,   0,   0,   0,   '|', 0,   0
	};
	int key_to = 0, key_shift = 0, key_leds = (binfo->leds >> 4) & 7, keycmd_wait = -1;
     
    // display area and auto move up 
    int start_row=0;
    int start_col=16;
    int end_row = 16*46;
    int end_col=16*60;
    int curr_row=start_row;
    // 字符缓冲区
    unsigned char *s2= (unsigned char *) memman_alloc_4k(memman, 65536*2);

	init_gdtidt();
	init_pic();// 这里设定了中断号与中断控制器PIC的对应关系
	
	fifo32_init(&fifo, 128, fifobuf, 0);
	init_pit();// 定时器
	init_keyboard(&fifo, 256);
	enable_mouse(&fifo, 512, &mdec);

	//屏蔽一些中断号
	io_out8(PIC0_IMR, 0x78); // 0111 1000, 屏蔽PIC上除0，1，2，7号外的所有中断，3，4，5，6)
	io_out8(PIC1_IMR, 0xEF); // 1110 1111, 屏蔽除了12号外的所有中断。 12号中断，即0x2C号中断，鼠标中断
	//开启中断
	io_sti();
	fifo32_init(&keycmd, 32, keycmd_buf, 0);
  
	memtotal = memtest(0x00400000, 0xbfffffff);
	memman_init(memman);
	memman_free(memman, 0x00001000, 0x0009e000); /* 0x00001000 - 0x0009efff */
	memman_free(memman, 0x00400000, memtotal - 0x00400000);

    net_buf = (int *)memman_alloc_4k(memman,1<<16);
    enable_net(&fifo_net);
    fifo32_init(&fifo_net,1<<16,net_buf,0);
	//netcard_init();


	init_palette();
	shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);
	task_a = task_init(memman);
	fifo.task = task_a;
	task_run(task_a, 1, 2);

	/* sht_back */
	sht_back  = sheet_alloc(shtctl);
	buf_back  = (unsigned char *) memman_alloc_4k(memman, binfo->scrnx * binfo->scrny);
	sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1); /* “§–¾F‚È‚µ */
	init_screen8(buf_back, binfo->scrnx, binfo->scrny);

	/* sht_cons */
	sht_cons = sheet_alloc(shtctl);
	buf_cons = (unsigned char *) memman_alloc_4k(memman, 256 * 165);
	sheet_setbuf(sht_cons, buf_cons, 256, 165, -1); /* “§–¾F‚È‚µ */
	make_window8(buf_cons, 256, 165, "BASH", 0);
	make_textbox8(sht_cons, 8, 28, 240, 128, COL8_000000);
	task_cons = task_alloc();
	task_cons->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 12;
	task_cons->tss.eip = (int) &console_task;
	task_cons->tss.es = 1 * 8;
	task_cons->tss.cs = 2 * 8;
	task_cons->tss.ss = 1 * 8;
	task_cons->tss.ds = 1 * 8;
	task_cons->tss.fs = 1 * 8;
	task_cons->tss.gs = 1 * 8;
	*((int *) (task_cons->tss.esp + 4)) = (int) sht_cons;
	*((int *) (task_cons->tss.esp + 8)) = memtotal;
	task_run(task_cons, 2, 2); /* level=2, priority=2 */
	sheet_slide(sht_cons, 512, 384);

	/* sht_win */
	sht_win   = sheet_alloc(shtctl);
	buf_win   = (unsigned char *) memman_alloc_4k(memman, 230 * 520);
	sheet_setbuf(sht_win, buf_win, 214, 520, -1); /* “§–¾F‚È‚µ */
	make_window8(buf_win, 214, 520, "RTL 8029 Registers", 1);
	make_textbox8(sht_win, 8, 28, 214-8*2, 520-8-28, COL8_FFFFFF);
	cursor_x = 8;
	cursor_c = COL8_FFFFFF;
	timer = timer_alloc();
	timer_init(timer, &fifo, 1);
	timer_settime(timer, 50);

	/* sht_mouse */
	sht_mouse = sheet_alloc(shtctl);
	sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99);
	init_mouse_cursor8(buf_mouse, 99);
	mx = (binfo->scrnx - 16) / 2; /* ‰æ–Ê’†‰›‚É‚È‚é‚æ‚¤‚ÉÀ•WŒvŽZ */
	my = (binfo->scrny - 28 - 16) / 2;

	sheet_slide(sht_back,  0,  0);
	sheet_slide(sht_cons, 1024-230-300, 56);
	sheet_slide(sht_win,  1024-230, 56);
	sheet_slide(sht_mouse, mx, my);
	sheet_updown(sht_back,  0);
	sheet_updown(sht_cons,  1);
	sheet_updown(sht_win,   2);
	sheet_updown(sht_mouse, 3);

	/* Å‰‚ÉƒL[ƒ{[ƒhó‘Ô‚Æ‚ÌH‚¢ˆá‚¢‚ª‚È‚¢‚æ‚¤‚ÉAÝ’è‚µ‚Ä‚¨‚­‚±‚Æ‚É‚·‚é */
	fifo32_put(&keycmd, KEYCMD_LED);
	fifo32_put(&keycmd, key_leds);
 
    check_pci(buf_back,binfo);
    show_pci_config(buf_back,binfo,0,5,0,16,1024-16*8);
                    
    read_nodeid(IOADDR,&mynodeid);
    write_nodeid2phy(IOADDR,mynodeid);
    /*
    FORSHOWINFO forshow;
    forshow.vram=buf_back;
    forshow.sht=sht_back;
    forshow.xsize=binfo->scrnx;
    forshow.start_col=start_col;
    forshow.start_row=start_row;
    forshow.end_col=end_col;
    forshow.end_row=end_row;
    */
    FORSHOWINFO forshow_s={buf_back,sht_back,binfo->scrnx,curr_row,start_col,start_row,end_col,end_row,COL8_FFFFFF,1};
    FORSHOWINFO * forshow =&(forshow_s);// 因为预定义函数的输入变量，必须是forshow,也必须是指针
    FORSHOWINFO forshow_win={buf_win,sht_win,sht_win->bxsize,28,8,24,16*13,16*30,COL8_000000,1};
    
	sprintf(s2, "[%d] MAC read from PAR: %02x",curr_row,GetRegisterValue(1,1));
	sprintf(s2, "%s-%02x",s2,GetRegisterValue(1,2));
	sprintf(s2, "%s-%02x",s2,GetRegisterValue(1,3));
	sprintf(s2, "%s-%02x",s2,GetRegisterValue(1,4));
	sprintf(s2, "%s-%02x",s2,GetRegisterValue(1,5));
	sprintf(s2, "%s-%02x",s2,GetRegisterValue(1,6));
	sprintf(s2,"%s,memtotal:%dM,%dM",s2,memman_total(memman)/(1024*1024),memtotal/(1024*1024));
	strshow(s2);
	
	MAC_PACKAGE *mac_p= (MAC_PACKAGE *) memman_alloc_4k(memman, sizeof(MAC_PACKAGE));

    // MAC header
    init_mac_header(mac_p);
    // IP header
	init_ip_package(&((mac_p->ip).header));
    mac_p->ip.header.head_checksum=calculate_checksum((short *)(&(mac_p->ip.header)),sizeof(mac_p->ip.header));
	
	// UDP header
    mac_p->ip.udp.src_port=hxl(68);
    mac_p->ip.udp.dest_port=hxl(67);
    mac_p->ip.udp.lenth=hxl(sizeof(mac_p->ip.udp)-4);
    //mac_p->ip.udp.lenth=sizeof(mac_p->ip.udp)-4;
    mac_p->ip.udp.checksum=0;

    struct UDP_PERSDO_PACKAGE *udp_persdo=(struct UDP_PERSDO_PACKAGE *)memman_alloc_4k(memman,sizeof(struct UDP_PERSDO_PACKAGE));
    udp_persdo->src_ip = 0x00000000;
    udp_persdo->dest_ip = 0xffffffff;
    udp_persdo->zeros=0x00;
    udp_persdo->protocal = 17;
    udp_persdo->length = sizeof(struct UDP_PERSDO_PACKAGE);
    
    
    // DHCP discover header
    init_discover_package(&(mac_p->ip.udp.discover));
    //init_discover_package(&(mac_p->ip.udp.discover));
    udp_persdo->udp=mac_p->ip.udp;
    mac_p->ip.udp.checksum = calculate_checksum((short *)udp_persdo, sizeof(*udp_persdo)/2);
    

    uchar * tmp_p;
    int     tmp_length;
    //show_str(&(forshow),"mac_header:");
    //show_str(&(forshow),"mac_header:");
    strshow("mac_header:");
    
    buffshow((unsigned char*)(mac_p)+2,14);
    
    strshow("ip header:");
    buffshow((unsigned char*)(&(mac_p->ip.header)),20);
    
    strshow("udp header:");
    tmp_p=(unsigned char *)(&(mac_p->ip.udp));
    tmp_length=8;
    curr_row=buffshow(tmp_p,tmp_length);
    
    strshow("dhcp discover:");
    tmp_p=(unsigned char *)(&(mac_p->ip.udp.discover));
    tmp_length=sizeof(mac_p->ip.udp.discover);
    curr_row=buffshow(tmp_p,tmp_length-2);
    curr_row=buffshow(((uchar*)mac_p)+2,sizeof(*mac_p)-4);

    
    //back_row=show_package(buf_back,binfo,(unsigned char *)(&(mac_p->ip.udp)),sizeof(mac_p->ip.udp)-2,back_row,"udp:",s2);
    //back_row=show_package(buf_back,binfo,(unsigned char *)(&(mac_p->ip.udp.discover)),sizeof(mac_p->ip.udp.discover)-2,back_row,"discover:",s2);

	
    netcard_init();
    //init_8390();
    // clear dma complete interrupt
    //page_select(0);
    //outb(0xff,IOADDR+0x07);
    //send_dhcp_discover(((unsigned char * )mac_p )+2,sizeof(*mac_p)-4);
    
    //WriteToDma(0x4000,15,0xaa);
    //page_select(0);
    //outb(0xff,IOADDR+0x07);
    //ReadFromDma(0x4000,sizeof(*mac_p)-2,dma_str);
    //back_row=show_package(buf_back,binfo,(unsigned char *)dma_str,sizeof(*mac_p)-2,back_row,"read data from dma:",s2);
                    
    //loopback_test(); 
    //page_select(0);
    //io_out8(0xc000+0x0e,0xff);
    //InitMAR();
    //Init4R();
	unsigned char * recv = (unsigned char *)memman_alloc_4k(memman,0xffff*2);
	memset(recv,0,0xffff*2);
	//show_register(buf_back,binfo,sht_back,0,5,0,15,1024-50*8);
	//sheet_refresh(sht_back,  0, 0, sht_back->bxsize,  sht_back->bysize);
    register_win(0,5,0);
    //show_refresh_strs(buf_back,sht_back,binfo->scrnx,300,50,(unsigned char *)(&(mac_p->ip.udp.discover)),sizeof(mac_p->ip.udp.discover)-2);
    strshow_win(" RTL-8209");
	
	for (;;) {
		if (fifo32_status(&keycmd) > 0 && keycmd_wait < 0) {
			/* ƒL[ƒ{[ƒhƒRƒ“ƒgƒ[ƒ‰‚É‘—‚éƒf[ƒ^‚ª‚ ‚ê‚ÎA‘—‚é */
			keycmd_wait = fifo32_get(&keycmd);
			wait_KBC_sendready();
			io_out8(PORT_KEYDAT, keycmd_wait);
		}
		io_cli();//进入for循环，先关闭中段，出for循环的时候再打开
        
		int fifo_length=fifo32_status(&fifo_net);
	    if(fifo_length>0){

    
            io_out8(IOADDR+0x07,0xFF);
	    	int ISR = fifo32_get(&fifo_net); 

	    	/*
            //bit-7   RST:reset 
            if((i&0x80)==0x80){
                sprintf(s2,"[info] reset status or recive buffer overflows...");
                //row=show_refresh_str(buf_back,sht_back,binfo->scrnx,300,row,s2);
                //strshow(s2);
            }
            //bit-6   RDC:remote  DMA operation complete
            if((i&0x40)==0x40){
                sprintf(s2,"[info] remote DMA operation complete...");	
                //row=show_refresh_str(buf_back,sht_back,binfo->scrnx,300,row,s2);
	    	    //strshow(s2);
            
            }
            //bit-5   CND:counter
            if((i&0x20)==0x20){
                sprintf(s2,"[info] counter...");
                //row=show_refresh_str(buf_back,sht_back,binfo->scrnx,300,row,s2);
	    	    //strshow(s2);
            
            }
            //bit-4   OVW:overview
            if((i&0x10)==0x10){
           	    sprintf(s2,"[error] overview...");	
          	}
            //bit-3   TXE:transsmit error
            if((i&0x08)==0x08){
           	    sprintf(s2,"[error] transmit error...");
           	    //row=show_refresh_str(buf_back,sht_back,binfo->scrnx,300,row,s2);
	
                //strshow(s2);
             }
            //bit-2   RXE:recive error
            if((i&0x04)==0x04){
          	    sprintf(s2,"[error] recive error...");
      	        //row=show_refresh_str(buf_back,sht_back,binfo->scrnx,300,row,s2);
	            strshow(s2);
            }
            //bit-1   PTX:transsmit success
            if((i&0x02)==0x02){
          	    sprintf(s2,"[success] transmit with no errors...");
          	    //row=show_refresh_str(buf_back,sht_back,binfo->scrnx,300,row,s2);
                strshow(s2);
            }
            */
            //bit-0   PRX:recive success
            if((ISR&0x01)==0x01){
            	strshow("");
               	sprintf(s2,"[success] recive with no errors...,fifostatus:%d",fifo32_status(&fifo_net));
            	strshow(s2);
            	unsigned char bnry,curr;
            	short length=0;
	            page_select(0);
	            //io_out8(IOADDR+7,0xff);
	            bnry=io_in8(IOADDR+3);// 读取bondory指针
	            page_select(1);
	            curr=io_in8(IOADDR+7);// 读取curr 指针
	            sprintf(s2,"bnry=%02x,curr=%02x,RSR=%02x",bnry,curr,io_in8(IOADDR+0x0C));
	            strshow(s2);
	          if(bnry+1!=curr){
	            	
                
                page_select(0);
                io_out8(IOADDR+9,bnry);// 把要读取的地址的高位放入寄存器
		        io_out8(IOADDR+8,0x00);
		        io_out8(IOADDR+0xb,1);// 把读取数据个数的高8位放入寄存器
		        io_out8(IOADDR+0xa,0);// 读取数据个数的低8位
                //io_in8(IOADDR+0x0a);//read 
                int j=0;
                for(j=0;j<(1<<8);j++)// 每次读一页的数据
        	          recv[j]=io_in8(IOADDR+0x10);
        	    uchar RSR = recv[0];
        	    if(RSR&0x01){
        	    	strshow("RSR's bit0=1");
                    //数据正常
                    sprintf(s2,"next_dma_read=%02x,length=%d,next_recv=%02x,j=%04x,ISR=%02x,RSR=%02d",*(recv+1),*((short*)(recv+2)),curr,j+1,ISR,RSR);
                    strshow(s2);
                    int showlen=(*((short*)(recv+2)));
                    // 避免读取数据错误时，尝试显示没有读取的数据
                    if(showlen>j)
                        showlen=j;
                    buffshow(recv,showlen);
                    //if(*((short*)(recv+2)))>j
                    // 这里没有做长度检查，可能会造成内存访问越界
                    //buffana(recv+4);
                    structana(recv,2);
                    strshow("");
                }
		        bnry++;



	            page_select(0);
	            // 将bnry 寄存器的值，设置为curr-1,就不会继续产生中断了
	            if(bnry>0x7F)
	            	bnry=0x4C;
	            io_out8(IOADDR+3,bnry);
	          }
	           
              register_win(0,5,0);
            
            }
            
            io_sti();//打开中断，可以接收新的中断状态字了
            
	    }
        
		
		if (fifo32_status(&fifo) == 0) {
			task_sleep(task_a);
			io_sti();
		} else {
			i = fifo32_get(&fifo);
			io_sti();
			if (256 <= i && i <= 511) { /* ƒL[ƒ{[ƒhƒf[ƒ^ */
				if (i < 0x80 + 256) { /* ƒL[ƒR[ƒh‚ð•¶ŽšƒR[ƒh‚É•ÏŠ· */
					if (key_shift == 0) {
						s[0] = keytable0[i - 256];
					} else {
						s[0] = keytable1[i - 256];
					}
				} else {
					s[0] = 0;
				}
				if ('A' <= s[0] && s[0] <= 'Z') {	/* “ü—Í•¶Žš‚ªƒAƒ‹ƒtƒ@ƒxƒbƒg */
					if (((key_leds & 4) == 0 && key_shift == 0) ||
							((key_leds & 4) != 0 && key_shift != 0)) {
						s[0] += 0x20;	/* ‘å•¶Žš‚ð¬•¶Žš‚É•ÏŠ· */
					}
				}
				if (s[0] != 0) { /* ’Êí•¶Žš */
					if (key_to == 0) {	/* ƒ^ƒXƒNA‚Ö */
						if (cursor_x < 128) {
							/* ˆê•¶Žš•\Ž¦‚µ‚Ä‚©‚çAƒJ[ƒ\ƒ‹‚ð1‚Âi‚ß‚é */
							s[1] = 0;
							putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, s, 1);
							cursor_x += 8;
						}
					} else {	/* ƒRƒ“ƒ\[ƒ‹‚Ö */
						fifo32_put(&task_cons->fifo, s[0] + 256);
					}
				}
				if (i == 256 + 0x0e) {	/* ƒoƒbƒNƒXƒy[ƒX */
					if (key_to == 0) {	/* ƒ^ƒXƒNA‚Ö */
						if (cursor_x > 8) {
							/* ƒJ[ƒ\ƒ‹‚ðƒXƒy[ƒX‚ÅÁ‚µ‚Ä‚©‚çAƒJ[ƒ\ƒ‹‚ð1‚Â–ß‚· */
							putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, " ", 1);
							cursor_x -= 8;
						}
					} else {	/* ƒRƒ“ƒ\[ƒ‹‚Ö */
						fifo32_put(&task_cons->fifo, 8 + 256);
					}
				}
				if (i == 256 + 0x1c) {	/* Enter */
					if (key_to != 0) {	/* ƒRƒ“ƒ\[ƒ‹‚Ö */
						fifo32_put(&task_cons->fifo, 10 + 256);
					}
					page_select(0);
					//outb(0xFF,IOADDR+0x07);
					int number=send_dhcp_discover(((unsigned char * )mac_p )+2,sizeof(*mac_p)-4);
					sprintf(s2,"package length=%d,send_length=%d",sizeof(*mac_p)-4,number);
					strshow(s2);
					buffshow(((unsigned char * )mac_p )+2,sizeof(*mac_p)-4);
					//buffana(((unsigned char * )mac_p )+2);
					structana(((unsigned char * )mac_p ),0);
					register_win(0,5,0);
				}
				if (i == 256 + 0x0f) {	/* Tab */
					if (key_to == 0) {
						key_to = 1;
						make_wtitle8(buf_win,  sht_win->bxsize,  "RTL 8029 Registers",  0);
						make_wtitle8(buf_cons, sht_cons->bxsize, "console", 1);
						cursor_c = -1; /* ƒJ[ƒ\ƒ‹‚ðÁ‚· */
						boxfill8(sht_win->buf, sht_win->bxsize, COL8_FFFFFF, cursor_x, 28, cursor_x + 7, 43);
						fifo32_put(&task_cons->fifo, 2); /* ƒRƒ“ƒ\[ƒ‹‚ÌƒJ[ƒ\ƒ‹ON */
					} else {
						key_to = 0;
						make_wtitle8(buf_win,  sht_win->bxsize,  "RTL 8029 Registers",  1);
						make_wtitle8(buf_cons, sht_cons->bxsize, "console", 0);
						cursor_c = COL8_000000; /* ƒJ[ƒ\ƒ‹‚ðo‚· */
						fifo32_put(&task_cons->fifo, 3); /* ƒRƒ“ƒ\[ƒ‹‚ÌƒJ[ƒ\ƒ‹OFF */
					}
					sheet_refresh(sht_win,  0, 0, sht_win->bxsize,  21);
					sheet_refresh(sht_cons, 0, 0, sht_cons->bxsize, 21);
				}
				if (i == 256 + 0x2a) {	/* ¶ƒVƒtƒg ON */
					key_shift |= 1;
				}
				if (i == 256 + 0x36) {	/* ‰EƒVƒtƒg ON */
					key_shift |= 2;
				}
				if (i == 256 + 0xaa) {	/* ¶ƒVƒtƒg OFF */
					key_shift &= ~1;
				}
				if (i == 256 + 0xb6) {	/* ‰EƒVƒtƒg OFF */
					key_shift &= ~2;
				}
				if (i == 256 + 0x3a) {	/* CapsLock */
					key_leds ^= 4;
					fifo32_put(&keycmd, KEYCMD_LED);
					fifo32_put(&keycmd, key_leds);
				}
				if (i == 256 + 0x45) {	/* NumLock */
					key_leds ^= 2;
					fifo32_put(&keycmd, KEYCMD_LED);
					fifo32_put(&keycmd, key_leds);
				}
				if (i == 256 + 0x46) {	/* ScrollLock */
					key_leds ^= 1;
					fifo32_put(&keycmd, KEYCMD_LED);
					fifo32_put(&keycmd, key_leds);
				}
				if (i == 256 + 0xfa) {	/* ƒL[ƒ{[ƒh‚ªƒf[ƒ^‚ð–³Ž–‚ÉŽó‚¯Žæ‚Á‚½ */
					keycmd_wait = -1;
				}
				if (i == 256 + 0xfe) {	/* ƒL[ƒ{[ƒh‚ªƒf[ƒ^‚ð–³Ž–‚ÉŽó‚¯Žæ‚ê‚È‚©‚Á‚½ */
					wait_KBC_sendready();
					io_out8(PORT_KEYDAT, keycmd_wait);
				}
				/* ƒJ[ƒ\ƒ‹‚ÌÄ•\Ž¦ */
				if (cursor_c >= 0) {
					boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);
				}
				sheet_refresh(sht_win, cursor_x, 28, cursor_x + 8, 44);
			} else if (512 <= i && i <= 767) { /* ƒ}ƒEƒXƒf[ƒ^ */
				if (mouse_decode(&mdec, i - 512) != 0) {
					/* ƒ}ƒEƒXƒJ[ƒ\ƒ‹‚ÌˆÚ“® */
					mx += mdec.x;
					my += mdec.y;
					if (mx < 0) {
						mx = 0;
					}
					if (my < 0) {
						my = 0;
					}
					if (mx > binfo->scrnx - 1) {
						mx = binfo->scrnx - 1;
					}
					if (my > binfo->scrny - 1) {
						my = binfo->scrny - 1;
					}
					sheet_slide(sht_mouse, mx, my);
					if ((mdec.btn & 0x01) != 0) {
						/* ¶ƒ{ƒ^ƒ“‚ð‰Ÿ‚µ‚Ä‚¢‚½‚çAsht_win‚ð“®‚©‚· */
						sheet_slide(sht_win, mx - 80, my - 8);
					}
				}
			} else if (i <= 1) { /* ƒJ[ƒ\ƒ‹—pƒ^ƒCƒ} */
				if (i != 0) {
					timer_init(timer, &fifo, 0); /* ŽŸ‚Í0‚ð */
					if (cursor_c >= 0) {
						cursor_c = COL8_000000;
					}
				} else {
					timer_init(timer, &fifo, 1); /* ŽŸ‚Í1‚ð */
					if (cursor_c >= 0) {
						cursor_c = COL8_FFFFFF;
					}
				}
				timer_settime(timer, 50);
				if (cursor_c >= 0) {
					boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);
					sheet_refresh(sht_win, cursor_x, 28, cursor_x + 8, 44);
				}
			}
		}
	}
}
